package com.matrix.framework.core.component;

import com.matrix.framework.core.annotation.validation.LogCollector;
import com.matrix.framework.core.common.result.Result;
import com.matrix.framework.core.i18n.I18n;
import com.matrix.framework.core.i18n.MessageConstants;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * JWT配置管理控制器
 * 
 * Copyright © 海平面工作室 版权所有
 *
 * @Author: Leo
 * @Create: 2025/06/23 23:25
 * @Since 1.2
 */
@RestController
@RequestMapping("/system/jwt-config")
public class JwtConfigController {

    private final JwtConfigManager jwtConfigManager;

    public JwtConfigController(JwtConfigManager jwtConfigManager) {
        this.jwtConfigManager = jwtConfigManager;
    }

    /**
     * 获取当前JWT配置
     */
    @GetMapping("/current")
    @PreAuthorize("hasAuthority('sysconfig:get')")
    public Mono<Result<Map<String, Object>>> getCurrentConfig() {
        Map<String, Object> config = new HashMap<>();
        config.put("expirationMinutes", jwtConfigManager.getCurrentJwtExpirationMinutes());
        config.put("refreshThresholdMinutes", jwtConfigManager.getCurrentRefreshThresholdMinutes());
        config.put("expirationMillis", Jwt.JWT_EXPIRATION);
        config.put("refreshThresholdMillis", Jwt.REFRESH_THRESHOLD);
        
        return Mono.just(Result.ok(config));
    }

    /**
     * 更新JWT过期时间
     */
    @PostMapping("/expiration")
    @PreAuthorize("hasAuthority('sysconfig:edit')")
    @LogCollector
    public Mono<Result<Object>> updateJwtExpiration(@RequestParam long expirationMinutes) {
        if (expirationMinutes <= 0 || expirationMinutes > 1440) { // 最大24小时
            return Mono.just(Result.fail().message("JWT过期时间必须在1-1440分钟之间"));
        }

        return jwtConfigManager.updateJwtExpiration(expirationMinutes)
                .then(Mono.just(Result.ok().message(I18n.getMessage(MessageConstants.UPDATE_SUCCESS))))
                .onErrorResume(e -> Mono.just(Result.fail().message(e.getMessage())));
    }

    /**
     * 更新JWT刷新阈值
     */
    @PostMapping("/refresh-threshold")
    @PreAuthorize("hasAuthority('sysconfig:edit')")
    @LogCollector
    public Mono<Result<Object>> updateRefreshThreshold(@RequestParam long thresholdMinutes) {
        if (thresholdMinutes <= 0 || thresholdMinutes >= jwtConfigManager.getCurrentJwtExpirationMinutes()) {
            return Mono.just(Result.fail().message("刷新阈值必须大于0且小于JWT过期时间"));
        }

        return jwtConfigManager.updateRefreshThreshold(thresholdMinutes)
                .then(Mono.just(Result.ok().message(I18n.getMessage(MessageConstants.UPDATE_SUCCESS))))
                .onErrorResume(e -> Mono.just(Result.fail().message(e.getMessage())));
    }

    /**
     * 批量更新JWT配置
     */
    @PostMapping("/batch-update")
    @PreAuthorize("hasAuthority('sysconfig:edit')")
    @LogCollector
    public Mono<Result<Object>> batchUpdateConfig(@RequestBody JwtConfigRequest request) {
        // 参数验证
        if (request.getExpirationMinutes() <= 0 || request.getExpirationMinutes() > 1440) {
            return Mono.just(Result.fail().message("JWT过期时间必须在1-1440分钟之间"));
        }
        
        if (request.getRefreshThresholdMinutes() <= 0 || 
            request.getRefreshThresholdMinutes() >= request.getExpirationMinutes()) {
            return Mono.just(Result.fail().message("刷新阈值必须大于0且小于JWT过期时间"));
        }

        return jwtConfigManager.updateJwtExpiration(request.getExpirationMinutes())
                .then(jwtConfigManager.updateRefreshThreshold(request.getRefreshThresholdMinutes()))
                .then(Mono.just(Result.ok().message(I18n.getMessage(MessageConstants.UPDATE_SUCCESS))))
                .onErrorResume(e -> Mono.just(Result.fail().message(e.getMessage())));
    }

    /**
     * 重新加载JWT配置
     */
    @PostMapping("/reload")
    //@PreAuthorize("hasAuthority('sysconfig:edit')")
    @LogCollector
    public Mono<Result<Object>> reloadConfig() {
        return jwtConfigManager.reloadJwtConfig()
                .then(Mono.just(Result.ok().message("JWT配置重新加载成功")))
                .onErrorResume(e -> Mono.just(Result.fail().message(e.getMessage())));
    }

    /**
     * JWT配置请求对象
     */
    public static class JwtConfigRequest {
        private long expirationMinutes;
        private long refreshThresholdMinutes;

        public long getExpirationMinutes() {
            return expirationMinutes;
        }

        public void setExpirationMinutes(long expirationMinutes) {
            this.expirationMinutes = expirationMinutes;
        }

        public long getRefreshThresholdMinutes() {
            return refreshThresholdMinutes;
        }

        public void setRefreshThresholdMinutes(long refreshThresholdMinutes) {
            this.refreshThresholdMinutes = refreshThresholdMinutes;
        }
    }
} 